package com.push.web.spider;

import com.push.framework.config.ServerConfig;
import io.github.bonigarcia.wdm.WebDriverManager;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;

public class WOSSpinder {
    private static int sleepTime = 10000;


    public static void main(String[] args){
        //String string = "D:/temp";
        //System.out.println(string.replaceAll("/", "\\\\"));

        String url = "https://www.webofscience.com/wos/woscc/summary/c86c1cb7-ec83-4194-9c40-43e20b5def92-54b803e9/relevance/1";
        try {
            WosDownloader(url,"D:\\temp","D:\\temp\\test.txt","excel");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void getWosData(String url, String downloadDir,String targetDir){
        downloadDir = downloadDir.replaceAll("/", "\\\\");
        try{
            Integer recordNum = 0;
            WebDriverManager.chromedriver().setup();
            // 2.新的下载地址为桌面（可以弄成某个文件夹路径而不要直接弄成死的静态路径）
            // 3.HashMap 中保存下载地址信息
            HashMap<String, Object> hashMap = new HashMap<>();
            System.out.println("==================");
            System.out.println("downloadDir:"+downloadDir);
            System.out.println("targetDir:"+targetDir);
            hashMap.put("download.default_directory", downloadDir);
            // 4.ChromeOptions 中设置下载路径信息，需要传入保存有下载路径的 HashMap
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.setExperimentalOption("prefs", hashMap);
            WebDriver driver = new ChromeDriver(chromeOptions);

            driver.get(url);
            Thread.sleep(sleepTime);
            String record_num = driver.findElement(By.cssSelector(".brand-blue")).getText();
            recordNum = Integer.valueOf(record_num.replaceAll(",", ""));
            System.out.println("检索结果总数："+recordNum);
            Thread.sleep(5000);
            //叉掉弹窗
            if (isWebElementExist(driver, By.cssSelector("#onetrust-accept-btn-handler"))){
                driver.findElement(By.cssSelector("#onetrust-accept-btn-handler")).click();
                Thread.sleep(3000);
            }
            if (isWebElementExist(driver, By.cssSelector("button.flex-display-align-center"))){
                driver.findElement(By.cssSelector("button.flex-display-align-center")).click();
                Thread.sleep(3000);
            }
            if (isWebElementExist(driver, By.cssSelector("#pendo-close-guide-5600f670"))){
                driver.findElement(By.cssSelector("#pendo-close-guide-5600f670")).click();
                Thread.sleep(1500);
            }
            int start = 1, idx = 0, flag = 1;
            while(start < recordNum){
                if (isWebElementExist(driver, By.cssSelector("#onetrust-accept-btn-handler"))){
                    Thread.sleep(3000);
                }
                int end = start+999;
                if (recordNum - start < 1000){
                    end = recordNum;
                }
                System.out.println(start+"-"+end);
                //txt每次最多导出500
                driver.findElement(By.cssSelector("button.cdx-but-md:nth-child(2) span:nth-child(1)")).click();
                Thread.sleep(1500);
                //选择导出格式为txt
                driver.findElement(By.cssSelector("#exportToFieldTaggedButton")).click();
                Thread.sleep(1500);
                //选择自定义记录条数
                driver.findElement(By.cssSelector("#radio3 label:nth-child(1) span:nth-child(1)")).click();
                Thread.sleep(1500);
                driver.findElement(By.cssSelector("#mat-input-"+idx)).sendKeys(Keys.BACK_SPACE);
                driver.findElement(By.cssSelector("#mat-input-"+idx)).sendKeys(String.valueOf(start));
                driver.findElement(By.cssSelector("#mat-input-"+(idx+1))).sendKeys(Keys.BACK_SPACE);
                driver.findElement(By.cssSelector("#mat-input-"+(idx+1))).sendKeys(Keys.BACK_SPACE);
                driver.findElement(By.cssSelector("#mat-input-"+(idx+1))).sendKeys(Keys.BACK_SPACE);
                driver.findElement(By.cssSelector("#mat-input-"+(idx+1))).sendKeys(Keys.BACK_SPACE);
                driver.findElement(By.cssSelector("#mat-input-"+(idx+1))).sendKeys(String.valueOf(end));
                //更改导出字段
                driver.findElement(By.cssSelector(".margin-top-5 button:nth-child(1)")).click();
                Thread.sleep(1500);
                //选择所需字段(excel:3完整/4自定义; txt:3完整/4完整+引文)
                driver.findElement(By.cssSelector("div.wrap-mode:nth-child(3) span:nth-child(1)")).click();
                Thread.sleep(1500);
                //点击导出
                driver.findElement(By.cssSelector("div.flex-align:nth-child(3) button:nth-child(1)")).click();
                String filename = waitUntilDonwloadCompleted(driver);
                readFileToOtherFile(downloadDir+"\\"+filename, targetDir);
                System.out.println(filename);
                System.out.println(start+"-"+end+' '+"done");
                start = start + 1000;
                idx = idx + 2;
                flag = flag + 1;
            }
            driver.quit();
        } catch (Exception e){
            e.printStackTrace();
        }
    }



    public long getWosResult(String url){
        Integer recordNum = 0;
        WebDriverManager.chromedriver().setup();
        WebDriver driver = new ChromeDriver();
        driver.get(url);
        try{
            Thread.sleep(5000);
        } catch (Exception exception){
            exception.printStackTrace();
        }
        String record_num = driver.findElement(By.cssSelector(".brand-blue")).getText();
        recordNum = Integer.valueOf(record_num.replaceAll(",", ""));
        System.out.println("检索结果总数："+recordNum);
        driver.quit();
        return Long.valueOf (recordNum);
    }

    /**
     *
     * @param url 检索结果网址;
     * @param dir 记录导出存储路径(文件夹);
     * @param format
     */
    public static void WosDownloader(String url, String dir, String targetDir, String format) throws InterruptedException {
        Integer recordNum = 0;
        WebDriverManager.chromedriver().setup();
        // 2.新的下载地址为桌面（可以弄成某个文件夹路径而不要直接弄成死的静态路径）
        // 3.HashMap 中保存下载地址信息
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("download.default_directory", dir);
        // 4.ChromeOptions 中设置下载路径信息，需要传入保存有下载路径的 HashMap
        ChromeOptions chromeOptions = new ChromeOptions();
        chromeOptions.setExperimentalOption("prefs", hashMap);
        WebDriver driver = new ChromeDriver(chromeOptions);

        driver.get(url);
        Thread.sleep(sleepTime);
        String record_num = driver.findElement(By.cssSelector(".brand-blue")).getText();
        recordNum = Integer.valueOf(record_num.replaceAll(",", ""));
        System.out.println("检索结果总数："+recordNum);


        //Thread.sleep(8000);
        //叉掉弹窗
        /*if (isWebElementExist(driver, By.cssSelector("#onetrust-accept-btn-handler"))){
            driver.findElement(By.cssSelector("#onetrust-accept-btn-handler")).click();
            Thread.sleep(3000);
        }*/
        if (isWebElementExist(driver, By.cssSelector("button.flex-display-align-center"))){
            driver.findElement(By.cssSelector("button.flex-display-align-center")).click();
            Thread.sleep(3000);
        }
        if (isWebElementExist(driver, By.cssSelector("#pendo-close-guide-5600f670"))){
            driver.findElement(By.cssSelector("#pendo-close-guide-5600f670")).click();
            Thread.sleep(1500);
        }
        int start = 1, idx = 0, flag = 1;
        while(start < recordNum){
            if (isWebElementExist(driver, By.cssSelector("#onetrust-accept-btn-handler"))){
                Thread.sleep(3000);
            }
            System.out.println(start+"-"+(start+999));
            if(format.equalsIgnoreCase("excel")){
                driver.findElement(By.xpath("//span[contains(text(),'导出')]")).click();
                Thread.sleep(3000);
                //选择导出格式为excel
                if(isWebElementExist(driver, By.cssSelector("#exportToExcelButton"))){
                    driver.findElement(By.cssSelector("#exportToExcelButton")).click();
                } else {
                    System.out.println("#exportToExcelButton is not exist");
                }
                Thread.sleep(1500);
                //选择自定义记录条数
                driver.findElement(By.cssSelector("#radio3 label:nth-child(1) span:nth-child(1)")).click();
                Thread.sleep(1500);
                driver.findElement(By.cssSelector("#mat-input-"+idx)).sendKeys(Keys.BACK_SPACE);
                driver.findElement(By.cssSelector("#mat-input-"+idx)).sendKeys(String.valueOf(start));
                driver.findElement(By.cssSelector("#mat-input-"+(idx+1))).sendKeys(Keys.BACK_SPACE);
                driver.findElement(By.cssSelector("#mat-input-"+(idx+1))).sendKeys(Keys.BACK_SPACE);
                driver.findElement(By.cssSelector("#mat-input-"+(idx+1))).sendKeys(Keys.BACK_SPACE);
                driver.findElement(By.cssSelector("#mat-input-"+(idx+1))).sendKeys(Keys.BACK_SPACE);
                driver.findElement(By.cssSelector("#mat-input-"+(idx+1))).sendKeys(String.valueOf(start+999));
                Thread.sleep(1500);
                //更改导出字段
                driver.findElement(By.cssSelector(".margin-top-5 button:nth-child(1)")).click();
                Thread.sleep(1500);
                //选择所需字段(excel:3完整/4自定义; txt:3完整/4完整+引文)
                driver.findElement(By.cssSelector("div.wrap-mode:nth-child(3) span:nth-child(1)")).click();
                Thread.sleep(1500);
                //点击导出
                driver.findElement(By.cssSelector("div.flex-align:nth-child(3) button:nth-child(1)")).click();
                //等待下载完毕
                Thread.sleep(15000);
                System.out.println(start+"-"+(start+999)+' '+"done");
                start = start + 1000;
                idx = idx + 2;
                flag = flag + 1;
            } else {
                //txt每次最多导出500
                driver.findElement(By.xpath("//span[contains(text(),'导出')]")).click();
                Thread.sleep(3000);
                //选择导出格式为txt
                driver.findElement(By.cssSelector("#exportToFieldTaggedButton")).click();
                Thread.sleep(1500);
                //选择自定义记录条数
                driver.findElement(By.cssSelector("#radio3 label:nth-child(1) span:nth-child(1)")).click();
                Thread.sleep(1500);
                driver.findElement(By.cssSelector("#mat-input-"+idx)).sendKeys(Keys.BACK_SPACE);
                driver.findElement(By.cssSelector("#mat-input-"+idx)).sendKeys(String.valueOf(start));
                driver.findElement(By.cssSelector("#mat-input-"+(idx+1))).sendKeys(Keys.BACK_SPACE);
                driver.findElement(By.cssSelector("#mat-input-"+(idx+1))).sendKeys(Keys.BACK_SPACE);
                driver.findElement(By.cssSelector("#mat-input-"+(idx+1))).sendKeys(Keys.BACK_SPACE);
                driver.findElement(By.cssSelector("#mat-input-"+(idx+1))).sendKeys(Keys.BACK_SPACE);
                driver.findElement(By.cssSelector("#mat-input-"+(idx+1))).sendKeys(String.valueOf(start+999));
                //更改导出字段
                driver.findElement(By.cssSelector(".margin-top-5 button:nth-child(1)")).click();
                Thread.sleep(1500);
                //选择所需字段(excel:3完整/4自定义; txt:3完整/4完整+引文)
                driver.findElement(By.cssSelector("div.wrap-mode:nth-child(3) span:nth-child(1)")).click();
                Thread.sleep(1500);
                //点击导出
                driver.findElement(By.cssSelector("div.flex-align:nth-child(3) button:nth-child(1)")).click();
                String filename = waitUntilDonwloadCompleted(driver);
                readFileToOtherFile(dir+"\\"+filename, targetDir);
                System.out.println(filename);
                Thread.sleep(15000);
                System.out.println(start+"-"+(start+999)+' '+"done");
                start = start + 1000;
                idx = idx + 2;
                flag = flag + 1;
            }
        }
        driver.quit();
    }

    public static boolean isWebElementExist(WebDriver driver, By selector) {
        try {
            driver.findElement(selector);
            return true;
        } catch(NoSuchElementException e) {
            return false;
        }
    }

    public static void readFileToOtherFile(String readFileName, String writeFileName){
        try {
            FileInputStream fis = new FileInputStream(readFileName);
            FileOutputStream fos = new FileOutputStream(writeFileName, true);
            int len=0;
            //一次读取多少字节的文件,这里可以选择tmp.txt的所有字节长度
            byte[] b = new byte[fis.available()];
            while((len=fis.read(b))!=-1){
                //对字节进行排序
                //Arrays.sort(b);
                fos.write(b,0,len);
                //fos.flush();
            }
        }catch(FileNotFoundException e){
            e.printStackTrace();
        }catch(IOException e){
            e.printStackTrace();
        }
    }

    public static String waitUntilDonwloadCompleted(WebDriver driver) throws InterruptedException {
        // Store the current window handle
        String mainWindow = driver.getWindowHandle();

        // open a new tab
        JavascriptExecutor js = (JavascriptExecutor)driver;
        js.executeScript("window.open()");
        // switch to new tab
        // Switch to new window opened
        for(String winHandle : driver.getWindowHandles()){
            driver.switchTo().window(winHandle);
        }
        // navigate to chrome downloads
        driver.get("chrome://downloads");

        JavascriptExecutor js1 = (JavascriptExecutor)driver;
        // wait until the file is downloaded
        Long percentage = (long) 0;
        while ( percentage!= 100) {
            try {
                percentage = (Long) js1.executeScript("return document.querySelector('downloads-manager').shadowRoot.querySelector('#downloadsList downloads-item').shadowRoot.querySelector('#progress').value");
                //System.out.println(percentage);
            }catch (Exception e) {
                // Nothing to do just wait
            }
            Thread.sleep(1000);
        }
        // get the latest downloaded file name
        String fileName = (String) js1.executeScript("return document.querySelector('downloads-manager').shadowRoot.querySelector('#downloadsList downloads-item').shadowRoot.querySelector('div#content #file-link').text");
        // get the latest downloaded file url
        String sourceURL = (String) js1.executeScript("return document.querySelector('downloads-manager').shadowRoot.querySelector('#downloadsList downloads-item').shadowRoot.querySelector('div#content #file-link').href");
        // file downloaded location
        String donwloadedAt = (String) js1.executeScript("return document.querySelector('downloads-manager').shadowRoot.querySelector('#downloadsList downloads-item').shadowRoot.querySelector('div.is-active.focus-row-active #file-icon-wrapper img').src");
        System.out.println("Download deatils");
        System.out.println("File Name :-" + fileName);
        System.out.println("Donwloaded path :- " + donwloadedAt);
        System.out.println("Downloaded from url :- " + sourceURL);
        // close the downloads tab2
        driver.close();
        // switch back to main window
        driver.switchTo().window(mainWindow);
        return fileName;
    }
}
